<template>
  <text v-if="icon" ref="textRef" class="mxp-icon" :class="[cusClass, rotateAnimation]" :style="[newStyle, cusStyle]" @click="emits('click')">
    {{ icon }}
  </text>
</template>

<script lang="ts" setup>
  import { type CSSProperties, type PropType, computed, onBeforeMount, ref, watch } from 'vue';
  import { type MxpIconFont, mxpIconFontMap } from './mxp-icon-font-map';
  import { publicStyeProps } from '../mxp-tool/utils/public-props';
  import type { $AllColorStr, $AllSizeUnitStr } from '@/mxp-ui/mxp-tool/types/interface';
  import type { TextInstance } from 'mxp-uni-types';

  // #ifdef APP-PLUS-NVUE
  import iconUrl from './iconfont.ttf';
  import { nvueRotateAnimation } from '../mxp-tool/utils/nvue';
  defineOptions({
    name: 'mxp-icon',
  });

  // #endif

  const props = defineProps({
    /** 图标大小 */
    size: { type: String as PropType<$AllSizeUnitStr>, default: '14px' },
    /** 图标颜色 */
    color: { type: String as PropType<$AllColorStr>, default: '#333333' },
    /** 自定义图标规则为:myicon-music-e617,图标前缀和字体名称相同-图标类名-图标unicode符 */
    name: { type: String as PropType<MxpIconFont>, default: '' },
    /** 是否一直旋转 */
    spin: { type: Boolean, default: false },
    /** 旋转动画时间 (单位毫秒) */
    animationDuration: { type: Number, default: 2000 },
    ...publicStyeProps, // 混淆props共有参数
  });
  const emits = defineEmits<{
    (e: 'click'): void;
  }>();

  // #ifdef APP-PLUS-NVUE
  const domModule = uni.requireNativePlugin('dom');
  const animation = uni.requireNativePlugin('animation');
  const textRef = ref<TextInstance | null>(null);
  // #endif

  /** 图标 */
  const icon = computed<string | null>(() => (props.name in mxpIconFontMap ? mxpIconFontMap[props.name].unicode : null));

  /** 样式 */
  const newStyle = computed<CSSProperties>(() => {
    const _newStyle: CSSProperties = {
      width: props.size,
      height: props.size,
      fontSize: props.size,
      lineHeight: props.size,
      color: props.color,
    };
    // #ifndef APP-PLUS-NVUE
    _newStyle.animationDuration = `${props.animationDuration}ms`;
    // #endif
    return _newStyle;
  });

  /** nvue 页面的旋转动画 */
  // #ifdef APP-PLUS-NVUE
  watch(
    () => props.spin,
    (state) => {
      setTimeout(() => {
        state && nvueRotateAnimation(animation, textRef.value, props.animationDuration);
      }, 1000);
    },
    { immediate: true }
  );
  // #endif

  /** 普通页面页面的旋转动画 */
  const rotateAnimation = computed<string>(() => {
    let rotateClass = '';
    // #ifndef APP-PLUS-NVUE
    rotateClass = props.spin ? 'rotate-animation' : '';
    // #endif
    return rotateClass;
  });

  onBeforeMount(() => {
    // #ifdef APP-PLUS-NVUE
    domModule.addRule('fontFace', {
      fontFamily: 'mxp-iconfont',
      src: `url('${iconUrl}')`,
    });
    // #endif
  });
</script>

<style scoped="scoped">
  /* #ifndef APP-PLUS-NVUE */
  @font-face {
    font-family: mxp-iconfont;
    font-style: normal;
    font-weight: normal;
    src: url('./iconfont.ttf') format('truetype');
    font-display: swap;
  }

  @keyframes font-rotate {
    0% {
      transform: rotate(0deg);
    }

    100% {
      transform: rotate(360deg);
    }
  }

  .rotate-animation {
    animation: font-rotate 0.3s infinite linear;
  }
  /* #endif */

  .mxp-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    margin: 0;
    font-family: mxp-iconfont;
    text-align: center;
  }
</style>
